/**
 * @file validation_utils.h
 * @brief 验证工具函数头文件
 * @details 本文件声明了104协议中各种验证功能，
 *          包括超时参数验证、地址范围验证、QOI验证等。
 * 
 * @author zyb
 * @date 2025-10-03
 * @version 1.0
 * 
 * @note 验证函数严格按照IEC 60870-5-104协议规范
 * @warning 所有验证函数都会进行严格的参数检查
 * 
 * @see protocol_types.h
 * @see constants.h
 * @see error_codes.h
 */

#ifndef VALIDATION_UTILS_H
#define VALIDATION_UTILS_H

#ifdef __cplusplus
extern "C" {
#endif

#include "../../types/include/protocol_types.h"
#include "../../error/include/error_codes.h"

/* ==================== 超时参数验证函数声明 ==================== */

/**
 * @brief 验证超时参数
 * @details 验证t0、t1、t2、t3超时参数是否符合协议规范
 * 
 * @param t0 建立连接超时 (1-255秒)
 * @param t1 发送或测试APDU超时 (1-255秒)
 * @param t2 无数据报文时确认超时 (1-255秒)
 * @param t3 长期空闲状态下发送测试帧超时 (1-255秒)
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_INVALID_PARAM: 无效参数
 * 
 * @note 验证包括参数范围检查和t2 < t1的关系检查
 * @warning 所有超时参数都必须在1-255秒范围内
 * 
 * @see TIMEOUT_T0_MIN
 * @see TIMEOUT_T0_MAX
 * @see TIMEOUT_T1_MIN
 * @see TIMEOUT_T1_MAX
 * @see TIMEOUT_T2_MIN
 * @see TIMEOUT_T2_MAX
 * @see TIMEOUT_T3_MIN
 * @see TIMEOUT_T3_MAX
 */
protocol_error_t validate_timeout_params(uint8_t t0, uint8_t t1, uint8_t t2, uint8_t t3);

/* ==================== 地址范围验证函数声明 ==================== */

/**
 * @brief 验证地址范围
 * @details 验证信息对象地址是否在指定版本的地址范围内
 * 
 * @param address 信息对象地址
 * @param version 协议版本 (1997或2002)
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_INVALID_PARAM: 无效参数
 *         - PROTOCOL_ERROR_INVALID_ADDRESS: 无效地址
 * 
 * @note 支持1997版和2002版地址范围验证
 * @warning 不支持的协议版本会导致验证失败
 * 
 * @see ADDR_TELEMETRY_START_1997
 * @see ADDR_TELEMETRY_END_1997
 * @see ADDR_ANALOG_START_1997
 * @see ADDR_ANALOG_END_1997
 * @see ADDR_CONTROL_START_1997
 * @see ADDR_CONTROL_END_1997
 * @see ADDR_TELEMETRY_START_2002
 * @see ADDR_TELEMETRY_END_2002
 * @see ADDR_ANALOG_START_2002
 * @see ADDR_ANALOG_END_2002
 * @see ADDR_CONTROL_START_2002
 * @see ADDR_CONTROL_END_2002
 * @see ADDR_ENERGY_START_2002
 * @see ADDR_ENERGY_END_2002
 * @see ADDR_PARAMETER_START_2002
 * @see ADDR_PARAMETER_END_2002
 */
protocol_error_t validate_address_range(uint32_t address, uint16_t version);

/**
 * @brief 验证公共地址
 * @details 验证公共地址是否在有效范围内
 * 
 * @param common_addr 公共地址
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_INVALID_ADDRESS: 无效地址
 * 
 * @note 公共地址范围：1-65535
 * @warning 超出范围的地址会导致验证失败
 * 
 * @see COMMON_ADDR_MIN
 * @see COMMON_ADDR_MAX
 */
protocol_error_t validate_common_address(uint16_t common_addr);

/* ==================== QOI验证函数声明 ==================== */

/**
 * @brief 验证QOI限定词
 * @details 验证QOI限定词是否符合协议规范
 * 
 * @param qoi QOI限定词值
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_INVALID_PARAM: 无效参数
 * 
 * @note 验证包括未用值检查、配套标准保留范围检查、整个站召唤检查、特殊用途保留范围检查
 * @warning 未用值(0)会导致验证失败
 * 
 * @see QOI_UNUSED
 * @see QOI_COMPANION_STANDARD_MIN
 * @see QOI_COMPANION_STANDARD_MAX
 * @see QOI_ENTIRE_STATION
 * @see QOI_SPECIAL_PURPOSE_MIN
 * @see QOI_SPECIAL_PURPOSE_MAX
 */
protocol_error_t validate_qoi(uint8_t qoi);

/* ==================== 序列号验证函数声明 ==================== */

/**
 * @brief 验证序列号
 * @details 验证发送和接收序列号是否在有效范围内
 * 
 * @param send_seq 发送序列号
 * @param receive_seq 接收序列号
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_INVALID_PARAM: 无效参数
 * 
 * @note 序列号范围：0-32767
 * @warning 超出范围的序列号会导致验证失败
 * 
 * @see MAX_SEND_SEQUENCE_NUMBER
 * @see MAX_RECEIVE_SEQUENCE_NUMBER
 */
protocol_error_t validate_sequence_numbers(uint16_t send_seq, uint16_t receive_seq);

/* ==================== 类型标识验证函数声明 ==================== */

/**
 * @brief 验证类型标识
 * @details 验证类型标识是否在有效范围内
 * 
 * @param type_id 类型标识
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_INVALID_PARAM: 无效参数
 * 
 * @note 验证包括常见类型标识检查和通用范围检查
 * @warning 类型标识不能为0
 * 
 * @see TYPE_ID_SINGLE_POINT
 * @see TYPE_ID_DOUBLE_POINT
 * @see TYPE_ID_MEASUREMENT_NORMALIZED
 * @see TYPE_ID_MEASUREMENT_SCALED
 * @see TYPE_ID_MEASUREMENT_SHORT_FLOAT
 * @see TYPE_ID_SINGLE_POINT_SOE
 * @see TYPE_ID_DOUBLE_POINT_SOE
 * @see TYPE_ID_FAULT_EVENT
 * @see TYPE_ID_SINGLE_COMMAND
 * @see TYPE_ID_DOUBLE_COMMAND
 * @see TYPE_ID_CLOCK_SYNC
 * @see TYPE_ID_TOTAL_INTERROGATION
 * @see TYPE_ID_ENERGY_INTERROGATION
 * @see TYPE_ID_TEST_COMMAND
 * @see TYPE_ID_RESET_PROCESS
 */
protocol_error_t validate_type_id(uint8_t type_id);

/* ==================== 传送原因验证函数声明 ==================== */

/**
 * @brief 验证传送原因
 * @details 验证传送原因是否在有效范围内
 * 
 * @param cot 传送原因
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_INVALID_PARAM: 无效参数
 * 
 * @note 验证包括常见传送原因检查和通用范围检查
 * @warning 传送原因不能为0
 * 
 * @see COT_PERIODIC
 * @see COT_BACKGROUND_SCAN
 * @see COT_SPONTANEOUS
 * @see COT_INITIALIZATION
 * @see COT_REQUEST
 * @see COT_ACTIVATION
 * @see COT_ACTIVATION_CONFIRM
 * @see COT_DEACTIVATION
 * @see COT_DEACTIVATION_CONFIRM
 * @see COT_ACTIVATION_TERMINATION
 * @see COT_REMOTE_COMMAND
 * @see COT_LOCAL_COMMAND
 * @see COT_FILE_TRANSFER
 * @see COT_RESPONSE_STATION_INTERROGATION
 * @see COT_RESPONSE_GROUP1
 * @see COT_RESPONSE_GROUP2
 * @see COT_RESPONSE_GROUP3
 * @see COT_RESPONSE_GROUP4
 * @see COT_RESPONSE_GROUP5
 * @see COT_RESPONSE_GROUP6
 * @see COT_RESPONSE_GROUP7
 * @see COT_RESPONSE_GROUP8
 * @see COT_RESPONSE_GROUP9
 * @see COT_RESPONSE_GROUP10
 * @see COT_RESPONSE_GROUP11
 * @see COT_RESPONSE_GROUP12
 * @see COT_RESPONSE_GROUP13
 * @see COT_RESPONSE_GROUP14
 * @see COT_RESPONSE_GROUP15
 * @see COT_RESPONSE_GROUP16
 */
protocol_error_t validate_cause_of_transmission(uint16_t cot);

/* ==================== 综合验证函数声明 ==================== */

/**
 * @brief 验证APDU基本参数
 * @details 验证APDU的基本参数是否有效
 * 
 * @param length APDU长度
 * @param send_seq 发送序列号
 * @param receive_seq 接收序列号
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_INVALID_PARAM: 无效参数
 * 
 * @note 验证包括APDU长度检查和序列号检查
 * @warning 所有参数都必须符合协议规范
 * 
 * @see APDU_MIN_LENGTH
 * @see APDU_MAX_LENGTH
 * @see MAX_SEND_SEQUENCE_NUMBER
 * @see MAX_RECEIVE_SEQUENCE_NUMBER
 */
protocol_error_t validate_apdu_basic_params(uint8_t length, uint16_t send_seq, uint16_t receive_seq);

/**
 * @brief 验证ASDU基本参数
 * @details 验证ASDU的基本参数是否有效
 * 
 * @param type_id 类型标识
 * @param cot 传送原因
 * @param common_addr 公共地址
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_INVALID_PARAM: 无效参数
 *         - PROTOCOL_ERROR_INVALID_ADDRESS: 无效地址
 * 
 * @note 验证包括类型标识检查、传送原因检查和公共地址检查
 * @warning 所有参数都必须符合协议规范
 * 
 * @see validate_type_id
 * @see validate_cause_of_transmission
 * @see validate_common_address
 */
protocol_error_t validate_asdu_basic_params(uint8_t type_id, uint16_t cot, uint16_t common_addr);

/* ==================== 简单验证函数声明 ==================== */

/**
 * @brief 验证信息地址是否有效
 * @param address 信息地址
 * @return 1表示有效，0表示无效
 */
int is_info_address_valid(uint32_t address);

/**
 * @brief 验证类型标识是否有效
 * @param type_id 类型标识
 * @return 1表示有效，0表示无效
 */
int is_type_id_valid(uint8_t type_id);

/**
 * @brief 验证传输原因是否有效
 * @param cot 传输原因
 * @return 1表示有效，0表示无效
 */
int is_cause_of_transmission_valid(uint16_t cot);

/**
 * @brief 验证公共地址是否有效
 * @param common_addr 公共地址
 * @return 1表示有效，0表示无效
 */
int is_common_address_valid(uint16_t common_addr);

/**
 * @brief 验证可变结构限定词是否有效
 * @param vsq 可变结构限定词
 * @return 1表示有效，0表示无效
 */
int is_vsq_valid(uint8_t vsq);

/**
 * @brief 验证单点信息质量是否有效
 * @param siq 单点信息质量
 * @return 1表示有效，0表示无效
 */
int is_siq_valid(uint8_t siq);

/**
 * @brief 验证双点信息质量是否有效
 * @param diq 双点信息质量
 * @return 1表示有效，0表示无效
 */
int is_diq_valid(uint8_t diq);

/**
 * @brief 验证品质描述符是否有效
 * @param qds 品质描述符
 * @return 1表示有效，0表示无效
 */
int is_qds_valid(uint8_t qds);

/**
 * @brief 验证命令限定词是否有效
 * @param qos 命令限定词
 * @return 1表示有效，0表示无效
 */
int is_qos_valid(uint8_t qos);

/**
 * @brief 验证询问限定词是否有效
 * @param qoi 询问限定词
 * @return 1表示有效，0表示无效
 */
int is_qoi_valid(uint8_t qoi);

/**
 * @brief 验证命令限定词是否有效
 * @param qoc 命令限定词
 * @return 1表示有效，0表示无效
 */
int is_qoc_valid(uint8_t qoc);

/**
 * @brief 验证标度化值是否有效
 * @param value 标度化值
 * @return 1表示有效，0表示无效
 */
int is_scaled_value_valid(int16_t value);

/**
 * @brief 验证归一化值是否有效
 * @param value 归一化值
 * @return 1表示有效，0表示无效
 */
int is_normalized_value_valid(int16_t value);

/**
 * @brief 验证短浮点数是否有效
 * @param value 短浮点数
 * @return 1表示有效，0表示无效
 */
int is_short_float_valid(float value);

#ifdef __cplusplus
}
#endif

#endif /* VALIDATION_UTILS_H */